package com.giscloud.amp.service.sys.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.giscloud.amp.dao.AmpStaffAuthMapper;
import com.giscloud.amp.dao.SysRegisterMapper;
import com.giscloud.amp.entity.AmpStaffAuthExample;
import com.giscloud.amp.entity.SysRegister;
import com.giscloud.amp.entity.SysRegisterExample;
import com.giscloud.amp.entity.dto.AmpStaffRoleDTO;
import com.giscloud.amp.entity.dto.SysRegisterDTO;
import com.giscloud.amp.entity.vo.AmpStaffAuthVO;
import com.giscloud.amp.entity.vo.SysRegisterVO;
import com.giscloud.amp.service.sys.SysRegisterService;
import com.giscloud.commons.utils.UUIDUtils;
import com.giscloud.datasource.page.PageInfo;
import com.github.pagehelper.PageHelper;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author:gxd
 * @Description:
 * @Date: 11:22 2018/2/26
 * @Modified By:
 */
@Service("sysRegisterService")
public class SysRegisterServiceImpl implements SysRegisterService {
    private final static Logger log = LoggerFactory.getLogger(SysRegisterServiceImpl.class);
    @Autowired
    private SysRegisterMapper sysRegisterMapper;
    @Autowired
    private AmpStaffAuthMapper ampStaffAuthMapper;

    @Override
    public List<SysRegisterVO> listSysRegister(){
        SysRegisterExample sysRegisterExample = new SysRegisterExample();
        SysRegisterExample.Criteria criteria = sysRegisterExample.createCriteria();
        criteria.andStatusCdEqualTo((short)1);
        List<SysRegisterVO> sysRegisterVOs = sysRegisterMapper.selectByExample(sysRegisterExample);
        return sysRegisterVOs;
    }


    @Override
    public PageInfo getSysRegisterList(SysRegisterDTO sysRegisterDTO) {
        log.debug("#getSysRegisterList parameter ={}", JSON.toJSONString(sysRegisterDTO));
        if(sysRegisterDTO.isNeedPagination()){
            PageHelper.startPage(sysRegisterDTO.getPage(), sysRegisterDTO.getRows());
        }
        SysRegisterExample sysRegisterExample = new SysRegisterExample();
        SysRegisterExample.Criteria criteria = sysRegisterExample.createCriteria();
        if(StringUtils.isNotBlank(sysRegisterDTO.getSystemName())){
            criteria.andSystemNameLike("%"+sysRegisterDTO.getSystemName()+"%");
        }
        if(sysRegisterDTO.getSystemId() != null){
            criteria.andSystemIdEqualTo(sysRegisterDTO.getSystemId());
        }
        criteria.andStatusCdEqualTo((short)1);
        List<SysRegisterVO> sysRegisterVOs = sysRegisterMapper.selectByExample(sysRegisterExample);
        return PageInfo.of(sysRegisterVOs);
    }

    @Override
    public SysRegisterVO getSysRegisterByCondition(SysRegisterDTO sysRegisterDTO) {
        log.debug("#getSysRegisterByCondition parameter ={}", JSON.toJSONString(sysRegisterDTO));
        SysRegisterExample sysRegisterExample = new SysRegisterExample();
        SysRegisterExample.Criteria criteria = sysRegisterExample.createCriteria();
        if(sysRegisterDTO.getSystemId() != null){
            criteria.andSystemIdEqualTo(sysRegisterDTO.getSystemId());
        }
        if(sysRegisterDTO.getStatusCd() != null){
            criteria.andStatusCdEqualTo((short)1);
        }
        log.debug("===========getSysRegisterByCondition从数据库查询=======");
        List<SysRegisterVO> sysRegisterVOs =  sysRegisterMapper.selectByExample(sysRegisterExample);
        if(!CollectionUtil.isEmpty(sysRegisterVOs) && sysRegisterVOs.size() == 1){
            return sysRegisterVOs.get(0);
        }else{
            return  null;
        }
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRED, rollbackFor=Exception.class)
    public int delete(Long systemId,String systemCode) {
        SysRegisterExample sysRegisterExample = new SysRegisterExample();
        SysRegisterExample.Criteria criteria = sysRegisterExample.createCriteria();
        if(systemId != null){
            criteria.andSystemIdEqualTo(systemId);
        }
        if(StringUtils.isNotBlank(systemCode)){
            criteria.andSystemCodeEqualTo(systemCode);
        }
        return sysRegisterMapper.deleteByExample(sysRegisterExample);
    }

    @Transactional(propagation= Propagation.REQUIRED, rollbackFor=Exception.class)
    @Override
    public int insert(SysRegisterDTO sysRegisterDTO) {
        SysRegister sysRegister = new SysRegister();
        BeanUtils.copyProperties(sysRegisterDTO,sysRegister);
        sysRegister.setCreatedDt(new Date());
        sysRegister.setVersion(new Date());
        sysRegister.setStatusCd((short) 1);
        sysRegister.setTokenExpDt(DateUtil.offsetDay(new Date(),30));
        sysRegister.setToken(UUIDUtils.getRandom32PK());
        return sysRegisterMapper.insertSelective(sysRegister);
    }

    @Transactional(propagation= Propagation.REQUIRED, rollbackFor=Exception.class)
    @Override
    public SysRegister update(SysRegisterDTO sysRegisterDTO) {
        SysRegisterExample sysRegisterExample = new SysRegisterExample();
        SysRegisterExample.Criteria criteria = sysRegisterExample.createCriteria();
        if(sysRegisterDTO.getSystemId() != null){
            criteria.andSystemIdEqualTo(sysRegisterDTO.getSystemId());
        }
        SysRegister sysRegister = new SysRegister();
        BeanUtils.copyProperties(sysRegisterDTO,sysRegister);
        sysRegister.setCreatedDt(new Date());
        sysRegister.setVersion(new Date());
        //暂时先不改系统令牌
        //sysRegister.setToken(UUIDUtils.getRandom32PK());
        //sysRegister.setTokenExpDt(DateUtil.offsetDay(new Date(),30));
        if(sysRegisterMapper.updateByExampleSelective(sysRegister,sysRegisterExample) >= 1){
            return sysRegister;
        }
        return null;
    }


    /**
     * 账号拥有角色，同时还有自己的权限，取两者的并集
     * @param ampStaffRoleDTO
     * @return
     */
    @Override
    public List<SysRegisterVO> getSysRegisterByDTO(AmpStaffRoleDTO ampStaffRoleDTO) {
        List<AmpStaffAuthVO> ampStaffAuthVOs = null;
        List<AmpStaffAuthVO> ampStaffRoleAuthVOs = null;
        List<AmpStaffAuthVO> ampStaffAuthVOsAll = new ArrayList<>();
        List<SysRegisterVO> sysRegisterVOS = null;
        //合并用户、角色的权限
        if(ampStaffRoleDTO.getStaffId() != null){
            AmpStaffAuthExample ampStaffAuthExample = new AmpStaffAuthExample();
            AmpStaffAuthExample.Criteria criteria = ampStaffAuthExample.createCriteria();
            criteria.andObjectIdEqualTo(ampStaffRoleDTO.getStaffId());
            criteria.andObjectTypeEqualTo((short)1);
            criteria.andStatusCdEqualTo((short)1);
            ampStaffAuthVOs = ampStaffAuthMapper.selectByExample(ampStaffAuthExample);
            ampStaffAuthVOsAll.addAll(ampStaffAuthVOs);
        }
        if(CollectionUtil.isNotEmpty(ampStaffRoleDTO.getRoles())){
            AmpStaffAuthExample ampStaffAuthExample = new AmpStaffAuthExample();
            AmpStaffAuthExample.Criteria criteria = ampStaffAuthExample.createCriteria();
            List<Long> list = ampStaffRoleDTO.getRoles().stream().
                    map(Long::parseLong).
                    collect(Collectors.toList());
            criteria.andObjectIdIn(list);
            criteria.andObjectTypeEqualTo((short)2);
            criteria.andStatusCdEqualTo((short)1);
            ampStaffRoleAuthVOs = ampStaffAuthMapper.selectByExample(ampStaffAuthExample);
            ampStaffAuthVOsAll.addAll(ampStaffRoleAuthVOs);
        }
        if(CollectionUtil.isEmpty(ampStaffAuthVOsAll)){
            return null;
        }
        //2、从amp_staff_auth表中取数据systemId，set去重
        Set<Long> systemIdSet = new HashSet<>();
        for (AmpStaffAuthVO staffAuthVO : ampStaffAuthVOsAll) {
            systemIdSet.add(staffAuthVO.getSystemId());
        }
        List<Long> systemIdList = new ArrayList<>(systemIdSet);
        //3、根据系统id取出系统相关信息
        if(CollectionUtil.isNotEmpty(systemIdList)){
            SysRegisterExample sysRegisterExample = new SysRegisterExample();
            SysRegisterExample.Criteria criteriaSysRegister = sysRegisterExample.createCriteria();
            if(CollectionUtil.isNotEmpty(systemIdList)){
                criteriaSysRegister.andSystemIdIn(systemIdList);
            }
            sysRegisterVOS = sysRegisterMapper.selectByExample(sysRegisterExample);
        }else{
            return null;
        }
        if(CollectionUtil.isEmpty(sysRegisterVOS)){
            return null;
        }
        return sysRegisterVOS;
    }

    @Override
    public List<SysRegisterVO> listSysRegisterByStaff(Long staffId) {
        Map map = new HashedMap();
        map.put("staffId",staffId);
        return sysRegisterMapper.listSysRegisterByStaff(map);
    }
}
